perm filename EMITER.SAI[HAL,HE]3 blob sn#210444 filedate 1976-04-09 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00004 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	ENTRY  COMMENT  INT_TO_FLOAT, COMERR, GENLABEL
C00005 00003	!  INITOUT, CLOSEOUT
C00007 00004	!  MAKE_REMARK, EMIT
C00013 ENDMK
C⊗;
ENTRY;  COMMENT  INT_TO_FLOAT, COMERR, GENLABEL;
BEGIN "emiter"

REQUIRE "ABBREV.SAI[S,RHT]" SOURCE_FILE;
REQUIRE "EMITER.HDR[HAL,HE]" SOURCE_FILE;
    !  That will define all the RELOC and PC constants;

INTERNAL PROCEDURE INT_TO_11FLOAT(REFERENCE INTEGER RES1, RES2; REAL ARG);
    BEGIN "inttf"
    !  ARG is transformed into two integers, NUM1 and NUM2, which
    represent that real in pdp11 floating format;
    INTEGER BYTE;
    REAL T;
    LABEL ST1, ST2;
    INTEGER NUM1, NUM2;
    BYTE←'013200000002;
    T ← ARG;
        START_CODE
                MOVE   2,T;
                JUMPGE 2,ST1;
                MOVN   2,2;
                TLO    2,'400000;
        ST1:    JFCL   2,ST2;
        ST2:    ADDI   2,4;
                DPB    2,BYTE;
                SETZ   1,;
                LSHC   1,16;
                MOVEM  1,NUM1;
                SETZ   1,;
                LSHC   1,16;
                MOVEM  1,NUM2;
        END;
    RES1 ← NUM1;
    RES2 ← NUM2;
    END "inttf";

INTERNAL PROCEDURE COMERR
  (STRING MESSG;RECORD_POINTER(ANY_CLASS) CONTXT (NULL_RECORD));
    !  Non-fatal warnings;
    BEGIN
    EXTERNAL RECURSIVE PROCEDURE ALPRIN
     (RECORD_POINTER(ANY_CLASS) S);
    IF CONTXT≠NULL_RECORD THEN ALPRIN(CONTXT);
    USERERR(0,1,"HAH!  "&MESSG);
    END;

INTERNAL INTEGER PROCEDURE GENLABEL;
    BEGIN  ! Makes a new label for the PALX output;
    OWN INTEGER LAB;
    RETURN(LAB ← LAB + 1);
    END;
!  INITOUT, CLOSEOUT;

INTEGER REL0;  !  Channel number;
INTEGER REL1;  !  Channel number;
INTEGER REL2;  !  Channel number;
! INTEGER REL3;  !  Channel number;

INTERNAL PROCEDURE INITOUT;
    BEGIN "initout" ! Initialize the four output streams, going to the files
    COMP.AL0, COMP.AL1, COMP.AL2, COMP.AL3;
    INTEGER COUNT, BRCHAR, EOF, FLAG;
    STRING PPN;
    PRINT("OUTPUT PPN ( [foo,bar] ) = ");
    PPN←INCHWL;
    REL0 ← GETCHAN;
    OPEN(REL0,"DSK",0,0,2,COUNT,BRCHAR,EOF);
    ENTER(REL0,"COMP.AL0"&PPN,FLAG);
    IF FLAG THEN COMERR("I can't enter COMP.AL0");
    REL1 ← GETCHAN;
    OPEN(REL1,"DSK",0,0,2,COUNT,BRCHAR,EOF);
    ENTER(REL1,"COMP.AL1"&PPN,FLAG);
    IF FLAG THEN COMERR("I can't enter COMP.AL1");
    REL2 ← GETCHAN;
    OPEN(REL2,"DSK",0,0,2,COUNT,BRCHAR,EOF);
    ENTER(REL2,"COMP.AL2"&PPN,FLAG);
    IF FLAG THEN COMERR("I can't enter COMP.AL2");
!   REL3 ← GETCHAN;
!   OPEN(REL3,"DSK",0,0,2,COUNT,BRCHAR,EOF);
!   ENTER(REL3,"COMP.AL3"&PPN,FLAG);
!   IF FLAG THEN COMERR("I can't enter COMP.AL3");
    END "initout";

INTERNAL PROCEDURE CLOSEOUT;
    BEGIN  ! Close all channels;
    CLOSE(REL0);
    CLOSE(REL1);
    CLOSE(REL2);
!   CLOSE(REL3);
    END;
!  MAKE_REMARK, EMIT;

STRING RSTRING;

INTERNAL PROCEDURE EMIT(INTEGER PC; REFERENCE INTEGER DATA, RELOC;
    INTEGER LTH (1));
    BEGIN "emit"
    !  Appends to current PAL files.  DATA and RELOC are the first
    words in a block of size LTH.  DATA holds the actual output, and
    RELOC holds relocation information about how to treat the word in
    DATA.  A record is kept of how many bytes have been stored for
    each PC;

    OWN INTEGER ARRAY WORDCOUNT [0:3];  !  How many words have been stored
	for this PC;

    INTEGER J, K, DAT, REL;
    EXTERNAL STRING ARRAY PSOP[1:300];
    REL ← CASE PC OF (REL0, REL1, REL2);

    FOR J ← 0 STEP 1 UNTIL LTH-1 DO
	BEGIN "emitloop"
	DAT ← MEMORY[LOC(DATA) + J];
	CASE MEMORY[LOC(RELOC) + J] OF
	    BEGIN "case"
            [PSINST]
                BEGIN "psinst"
		IF PC ≠ PSDCODE
		THEN COMERR("Outputting a pseudo-instruction, PC is not PSDCODE.");
		OUT(REL,TAB & PSOP[DAT] & CRLF);
		WORDCOUNT[PC] ← WORDCOUNT[PC] + 1;
                END "psinst";
            [SYMDEC]
                OUT(REL,"L" & CVOS(DAT) & ":");
            [SYMREF]
		BEGIN "symref"
                OUT(REL,(TAB & "L") & CVOS(DAT) & CRLF);
		WORDCOUNT[PC] ← WORDCOUNT[PC] + 1;
		END "symref";
            [REMARK]
                OUT(REL,(TAB & TAB & ";") & RSTRING & CRLF);
            [SKIP]
		BEGIN "skip"
                OUT(REL,(TAB & ".BLKW" & TAB) & CVOS(DAT) & CRLF);
		WORDCOUNT[PC] ← WORDCOUNT[PC] + DAT;
		END "skip";
            [CONST]
                BEGIN "const"
		OUT(REL,TAB & CVOS(DAT) & CRLF);
		WORDCOUNT[PC] ← WORDCOUNT[PC] + DAT;
                END "const";
	    [STRCONST]
                BEGIN "strconst"
                !  DAT is the location of a string itemvar whose
                datum is the string constant;
                STRING STR;
                STR ← DATUM(MEMORY[DAT,ITEMVAR],STRING);
                OUT(REL,TAB & "ASCIE </" & STR & "/>" & CRLF);
                WORDCOUNT[PC] ← WORDCOUNT[PC] + (LENGTH(STR)+1) DIV 2;
                END "strconst"
	    END "case";
	END "emitloop";
    END "emit";

INTERNAL PROCEDURE MAKE_REMARK(INTEGER PC;STRING REMK);
    BEGIN "make_remark"  !  Outputs this remark to the PAL file;
    RSTRING ← REMK;
    EMIT(PC,0,REMARK);
    END "make_remark";

END "emiter";